package com.dk.api.service.impl;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.dk.api.dao.ApiActionExVarDao;
import com.dk.api.entity.ApiActionExVarEntity;
import com.dk.api.entity.dto.ApiActionDTO;
import com.dk.api.entity.vo.ApiActionVO;
import com.dk.api.service.ApiActionExVarService;
import com.dk.common.utils.Constant;
import com.dk.common.utils.R;
import org.apache.logging.log4j.util.Strings;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dk.common.utils.PageUtils;
import com.dk.common.utils.Query;

import com.dk.api.dao.ApiActionDao;
import com.dk.api.entity.ApiActionEntity;
import com.dk.api.service.ApiActionService;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;


@Service("apiActionService")
public class ApiActionServiceImpl extends ServiceImpl<ApiActionDao, ApiActionEntity> implements ApiActionService {
    @Autowired
    ApiActionDao apiActionDao;

    @Autowired
    ApiActionExVarDao apiActionExVarDao;

    @Autowired
    ApiActionExVarService apiActionExVarService;



    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<ApiActionEntity> page = this.page(
                new Query<ApiActionEntity>().getPage(params),
                new QueryWrapper<ApiActionEntity>()
        );

        return new PageUtils(page);
    }

    /**
     * 根据参数查询动作列表
     * @param data
     * @return
     */
    @Override
    public R queryActionListByParams(ApiActionDTO data) {
        IPage<ApiActionVO> iPage = apiActionDao.queryActionList(new Page<>(data.getPage(),data.getLimit()),data);
        return R.ok().put(Constant.PAGE,new PageUtils(iPage));
    }

    /**
     * 保存动作信息
     * @param data 动作数据
     * @return 是否成功
     */
    @Transactional
    @Override
    public R saveActionInfo(ApiActionVO data) {
        if(apiActionDao.selectCount(new QueryWrapper<ApiActionEntity>().eq("action_name",data.getActionName()))>0){
            return R.error(Constant.statusCode.REQ_ERROR.getCode(), "动作名称已存在,请重新输入");
        }
        ApiActionEntity apiActionEntity = new ApiActionEntity();
        List<ApiActionExVarEntity> apiActionExVarList = data.getApiActionExVarList();
        BeanUtils.copyProperties(data,apiActionEntity);
        Integer num = apiActionDao.insert(apiActionEntity);
        if(num==0){
            return R.error(Constant.statusCode.REQ_ERROR.getCode(), "动作数据保存失败");
        }
        if(apiActionEntity.getActionType()==1||apiActionEntity.getActionType()==2){
            Integer actionId = apiActionEntity.getActionId();
            if(apiActionExVarList.size()!=0){
                apiActionExVarList.stream().map(apiActionExVar-> {
                    apiActionExVar.setActionId(actionId);
                    return apiActionExVar;
                }).collect(Collectors.toList());
                num = apiActionDao.saveApiActionExVarList(apiActionExVarList);
                if(num==0){
                    return R.error(Constant.statusCode.REQ_ERROR.getCode(), "操作组数据保存失败");
                }
            }
        }
        return R.ok();
    }

    /**
     * 根据动作id查询动作信息
     * @param actionId 动作id
     * @return 动作信息
     */
    @Override
    public R getActionInfoById(Integer actionId) {
        ApiActionVO apiActionVO = apiActionDao.selectActionInfoById(actionId);
        return R.ok().put(Constant.DATA,apiActionVO);
    }

    /**
     * 修改动作信息
     * @param data
     * @return
     */
    @Transactional
    @Override
    public R updateActionInfo(ApiActionVO data) {
        //校验动作id是否为空
        if(data.getActionId()!=null&&data.getActionId()!=0){
            ApiActionEntity apiActionEntity = new ApiActionEntity();
            //复制VO的action部分进行更新
            BeanUtils.copyProperties(data,apiActionEntity);
            apiActionDao.updateById(apiActionEntity);
            //当动作类型为case和select时更新操作组部分
            if(apiActionEntity.getActionType()==1||apiActionEntity.getActionType()==2) {
                //获取操作组集合
                List<ApiActionExVarEntity> apiActionExVarEntityList = data.getApiActionExVarList();
                //当操作组集合长度不为0时
                if (apiActionExVarEntityList.size() != 0) {
                    //过滤操作组id为空的操作组对象集合
                    List<ApiActionExVarEntity> insertList = apiActionExVarEntityList.stream().filter(apiActionExVarEntity -> {
                        return apiActionExVarEntity.getExVarId()==null||apiActionExVarEntity.getExVarId()==0;
                    }).collect(Collectors.toList());
                    //当操作组id为空集合不为空时,将动作id塞到操作组id中,进行插入操作
                    if(!ObjectUtils.isEmpty(insertList)){
                        insertList.stream().map(apiActionExVar-> {
                            apiActionExVar.setActionId(data.getActionId());
                            return apiActionExVar;
                        }).collect(Collectors.toList());
                        int num = apiActionDao.saveApiActionExVarList(insertList);
                        if(num==0){
                            return R.error(Constant.statusCode.REQ_ERROR.getCode(), "操作组数据保存失败");
                        }
                    }
                    //获取数据库中当前动作下所有的操作组对象组成集合
                    List<ApiActionExVarEntity> nowApiActionExVarEntityList = apiActionExVarDao
                            .selectList(new QueryWrapper<ApiActionExVarEntity>().eq("action_id",data.getActionId()));
                    //需要编辑的操作组对象集合
                    List<ApiActionExVarEntity> updateList = apiActionExVarEntityList.stream().filter(apiActionExVarEntity -> {
                        return apiActionExVarEntity.getExVarId()!=null||apiActionExVarEntity.getExVarId()!=0;
                    }).collect(Collectors.toList());
                    List<Integer> deleteList = new ArrayList<>();
                    //当数据库的操作组对象集合长度大于前端传的操作组对象集合,找出差集进行删除更新
                    if(updateList.size()<nowApiActionExVarEntityList.size()){
                        updateList.stream().forEach(apiActionExVarEntity->{
                            if(!nowApiActionExVarEntityList.contains(apiActionExVarEntity)){
                                deleteList.add(apiActionExVarEntity.getExVarId());
                            }
                        });
                        if(deleteList.size()!=0){
                            int num = apiActionExVarDao.deleteBatchIds(deleteList);
                            if(num==0){
                                return R.error(Constant.statusCode.REQ_ERROR.getCode(), "编辑过程中删除操作组数据失败");
                            }
                        }
                    }
//                    List<ApiActionExVarEntity> finalDeleteList = deleteList;
//                    apiActionExVarEntityList.stream().filter(apiActionExVarEntity->{
//                        return apiActionExVarEntity.getExVarId()!=null&&finalDeleteList!=null?!finalDeleteList.contains(apiActionExVarEntity):true;
//                    }).collect(Collectors.toList());
                    apiActionExVarService.updateBatchById(updateList);
                }
            }
        }else{
            return R.error(Constant.statusCode.REQ_ERROR.getCode(), "动作id不能为0或者空");
        }
        return R.ok();
    }

    /**
     * 根据id集合删除动作信息
     * @param data
     * @return
     */
    @Transactional
    @Override
    public R deleteActionInfoByIds(List<Integer> data) {
        Integer deleteNum = apiActionDao.deleteBatchIds(data);
        if(deleteNum==0){
            return R.error(Constant.statusCode.REQ_ERROR.getCode(), "删除动作信息失败");
        }
        QueryWrapper<ApiActionExVarEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.in("action_id",data);
        apiActionExVarDao.delete(queryWrapper);
        return R.ok();
    }

}